﻿using Microsoft.AspNetCore.Mvc.Filters;
using RQX.Common.Web.Core.Entity;
using RQX.Common.Web.Core.Valid;
using RQX.Common.Web.Tools;
using System;
using System.ComponentModel.DataAnnotations.Schema;

namespace RQX.Common.Web.Logger.InterfaceLogger
{
    /// <summary>
    /// 接口日志
    /// </summary>
    [Table("BS_LOG_INTERFACE")]
    public class InterfaceLog : CreateUserEntity
    {
        /// <summary>
        /// 请求来源IP地址
        /// </summary>
        [ApolloMaxLength(50)]
        public string source_ip { get; set; }
        /// <summary>
        /// 请求来源端口
        /// </summary>
        public int source_port { get; set; }
        /// <summary>
        /// 请求目标IP地址
        /// </summary>
        [ApolloMaxLength(50)]
        public string target_ip { get; set; }
        /// <summary>
        /// 请求目标端口
        /// </summary>
        public int target_port { get; set; }
        /// <summary>
        /// HTTP请求方式
        /// </summary>
        [ApolloMaxLength(20)]
        public string http_method { get; set; }
        /// <summary>
        /// 请求area名称
        /// </summary>
        [ApolloMaxLength(50)]
        public string area_name { get; set; }
        /// <summary>
        /// 请求controller名称
        /// </summary>
        [ApolloMaxLength(50)]
        public string controller_name { get; set; }
        /// <summary>
        /// 请求action名称
        /// </summary>
        [ApolloMaxLength(50)]
        public string action_name { get; set; }
        /// <summary>
        /// 请求完整路由地址
        /// </summary>
        [ApolloMaxLength(200)]
        public string request_route { get; set; }
        /// <summary>
        /// 请求url地址
        /// </summary>
        [ApolloMaxLength(200)]
        public string request_url { get; set; }
        /// <summary>
        /// 请求参数
        /// </summary>
        public string request_params { get; set; }
        /// <summary>
        /// 请求头
        /// </summary>
        public string request_header { get; set; }
        /// <summary>
        /// 请求时间
        /// </summary>
        [Column(TypeName = "datetime")]
        public DateTime request_time { get; set; }
        /// <summary>
        /// 响应时间
        /// </summary>
        [Column(TypeName = "datetime")]
        public DateTime response_time { get; set; }
        /// <summary>
        /// 响应json数据
        /// </summary>
        public string response_json { get; set; }
        /// <summary>
        /// 接口耗时，单位毫秒
        /// </summary>
        public double use_time { get; set; }
        /// <summary>
        /// 异常编号
        /// </summary>
        [ApolloMaxLength(40)]
        public string exception_code { get; set; }

        public InterfaceLog() { }
        public InterfaceLog(ActionExecutingContext context)
        {
            var connectionInfo = context.HttpContext.Connection;
            source_ip = connectionInfo.RemoteIpAddress.ToString();
            source_port = connectionInfo.RemotePort;
            target_ip = connectionInfo.LocalIpAddress.ToString();
            target_port = connectionInfo.LocalPort;

            var routeData = context.RouteData.Values;
            routeData.TryGetValue("area", out var area);
            routeData.TryGetValue("controller", out var controller);
            routeData.TryGetValue("action", out var action);
            area_name = area?.ToString();
            controller_name = controller?.ToString();
            action_name = action?.ToString();

            var request = context.HttpContext.Request;
            http_method = request.Method;
            request_route = request.Path.Value;
            request_url = request.Host.Value + request.Path.Value;
            request_time = DateTime.Now;
            request_header = request.Headers.ToJson();

            if (http_method.ToLower().Equals("get"))
            {
                request_params = request.QueryString.Value;
            }
            else
            {
                var paramsJson = "";
                context.ActionArguments.ForEach(k => paramsJson += k.Value.ToJson());
                request_params = paramsJson;
            }
        }

        /// <summary>
        /// 添加返回json
        /// </summary>
        /// <param name="responseJson"></param>
        /// <returns></returns>
        public InterfaceLog AddResponseJson(string responseJson)
        {
            response_json = responseJson;
            response_time = DateTime.Now;
            use_time = Math.Round((response_time - request_time).TotalMilliseconds, 1);
            return this;
        }
        /// <summary>
        /// 获取接口简要信息
        /// </summary>
        /// <returns></returns>
        public InterfaceLog TransferToSimple()
        {
            source_ip = string.Empty;
            source_port = -1;
            target_ip = string.Empty;
            target_port = -1;
            http_method = string.Empty;
            area_name = string.Empty;
            controller_name = string.Empty;
            action_name = string.Empty;
            request_route = string.Empty;
            request_header = string.Empty;
            response_json = string.Empty;
            return this;
        }
    }
}
